package csel.controller;

import java.util.Iterator;

import junit.framework.TestCase;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import csel.controller.factories.ControllerBuilder;
import csel.controller.factories.ModelCommandFactory;
import csel.controller.factories.ViewCommandFactory;
import csel.controller.listeners.AbstractActionListener;
import csel.controller.listeners.AreaViewActionListener;
import csel.controller.listeners.KeyboardListener;
import csel.controller.listeners.SplashViewActionListener;
import csel.controller.listeners.StatusViewActionListener;
import csel.model.Model;
import csel.view.AreaViewport;
import csel.view.Splasher;
import csel.view.StatusViewport;

public class TestControllerBuilder extends TestCase
{
	// THIS CLASS DOES NOT WORK
	
	static Model model = new Model();
	Splasher splashViewport = new Splasher( model );
	AreaViewport areaViewport = new AreaViewport( model );
	StatusViewport statusViewport = new StatusViewport( model );
	ControllerBuilder cb = new ControllerBuilder(model, null, areaViewport, statusViewport);
	
	// run the test
	public static void main(String args[])
	{
		junit.textui.TestRunner.run(TestControllerBuilder.class);
	}
	
	@Test
	public void testControllerConstruction()
	{
		// fairly crappy but simple test
		cb.contruct();
		Assert.assertNotNull(cb.getAList());
		Assert.assertNotNull(cb.getKList());
		Assert.assertNotNull(cb.getModelDispatcher());
		Assert.assertNotNull(cb.getViewDispatcher());
	}
	
	@Test
	public void testThreadsProduceAppropriateObjects()
	{
		cb.contruct();
		AreaViewActionListener aval = new AreaViewActionListener(
				cb.getModelDispatcher(), cb.getViewDispatcher(), new ModelCommandFactory( model, splashViewport, areaViewport, statusViewport ),
				new ViewCommandFactory( model, splashViewport, areaViewport, statusViewport ));
		SplashViewActionListener spval = new SplashViewActionListener(
				cb.getModelDispatcher(), cb.getViewDispatcher(), new ModelCommandFactory( model, splashViewport, areaViewport, statusViewport ),
				new ViewCommandFactory( model, splashViewport, areaViewport, statusViewport ));
		StatusViewActionListener stval = new StatusViewActionListener(
				cb.getModelDispatcher(), cb.getViewDispatcher(), new ModelCommandFactory( model, splashViewport, areaViewport, statusViewport ),
				new ViewCommandFactory( model, splashViewport, areaViewport, statusViewport ));
		KeyboardListener kval = new KeyboardListener(
				cb.getModelDispatcher(), cb.getViewDispatcher(), new ModelCommandFactory( model, splashViewport, areaViewport, statusViewport ),
				new ViewCommandFactory( model, splashViewport, areaViewport, statusViewport ));
		
		Assert.assertTrue(cb.getAList().get(0).getClass().equals(aval.getClass()));
		Assert.assertTrue(cb.getAList().get(1).getClass().equals(spval.getClass()));
		Assert.assertTrue(cb.getAList().get(2).getClass().equals(stval.getClass()));
		Assert.assertTrue(cb.getKList().get(0).getClass().equals(kval.getClass()));
		
		Assert.assertTrue(cb.getAList().get(0).getEventDecoder().getClass().equals(aval.getEventDecoder().getClass()));
		Assert.assertTrue(cb.getAList().get(1).getEventDecoder().getClass().equals(spval.getEventDecoder().getClass()));
		Assert.assertTrue(cb.getAList().get(2).getEventDecoder().getClass().equals(stval.getEventDecoder().getClass()));
		Assert.assertTrue(cb.getKList().get(0).getEventDecoder().getClass().equals(kval.getEventDecoder().getClass()));
		
		// terminate threads
		Iterator<KeyboardListener> i = cb.getKList().iterator();
		while( i.hasNext() )
		{
			i.next().killWorker();
		}
		Iterator<AbstractActionListener> j = cb.getAList().iterator();
		while( j.hasNext() )
		{
			j.next().killWorker();
		}
	}

	@Before
	protected void setup() throws Exception
	{
		super.setUp();
	}

	@After
	protected void tearDown() throws Exception
	{
		super.tearDown();
	}
}
